import java.util.ArrayList;

/**
 * Calibrate a person's persona for the purpose of mapping it later.
 * @author nate
 *
 */

public class Persona{
    public static final int TIME_STROKE = 0;
    public static final int AVG_POINT_TIME = 1;
    public static final int EUCLIDEAN_LENGTH = 2;
    public static final int STROKE_LENGTH = 3;
    public static final int MANHATTAN_DISTANCE = 4;
    public static final int EUCLIDEAN_SPEED = 5;
    public static final int TOTAL_SPEED = 6;
    public static final int MANHATTAN_SPEED = 7;
    public static final int ENDPOINT_CURVATURE = 8;
    public static final int TOTAL_CURVATURE = 9;
    public static final int ABSOLUTE_CURVATURE = 10;
    public static final int CURVATURE_CHANGES = 11;
    public static final int STROKE_JERKINESS = 12;
    public static final int START_TO_END_PRESSURE_DIFFERENCE = 13;
    public static final int MIDDLE_TO_ENDS_PRESSURE_DIFFERENCE = 14;
    public static final int AVERAGE_PRESSURE = 15;
    public static final int PRESSURE_DIFF = 16;
    public static final int ABS_PRESSURE_DIFF = 17;
    public static final int PRESSURE_TIME = 18;
    public static final int WEIGHT = 19;
    public static final int FIRST_EIGHTH_VERSUS_LAST_THIRD_TIME = 20;
    public static final int AVERAGE_TILT_X = 21;
    public static final int AVERAGE_TILT_Y = 22;
    public static final int SIZE_BOUNDING_BOX = 23;
    public static final int ANGLE_BOUNDING_BOX = 24;
    public static final int AVERAGE_TILT = 25;
    public static final int TOP_SPEED = 26;
    public static final int SLOWEST_SPEED = 27;
    public static final int BEGINNING_ANGLE = 28;
    public static final int ASPECT_RATIO = 29;
    public static final int ASPECT_RATIO_LOG = 30;
    public static final int ENDPOINT_ANGLE = 31;
    public static final int STROKE_SHARPNESS = 32;
    public static final int LOG_AREA = 33;
    public static final int TOTAL_TILT = 34;
    public static final int NUM_INTERSECTIONS = 35;
    public static final int LONGEST_STRAIGHT = 36;
    public static final int CENTROID = 37;
    public static final int CENTER_DISTANCE = 38;
    public static final int SECOND_QUARTER_VERSUS_LAST_QUARTER_PRESSURE = 39;
    
    ArrayList<FeatureAverages> averages;
    
    Persona(){
        
    }
    
    Persona(ArrayList<Stroke> strokes){
        averages = new ArrayList<FeatureAverages>();
        for(int i=0; i<40; i++){ 
            averages.add(new FeatureAverages(i, calculateAverage(strokes, i)));
        }
    }
    
    public double getFeatureAverage(int feature){
        return averages.get(feature).getAverage();
    }
    
    private static double calculateAverage(ArrayList<Stroke> strokes, int feature){
        double average = 0;
        for(int j=0; j<strokes.size(); j++){
            try{
            average += calculateFeature(strokes.get(j), feature);
            }
            catch(Exception ex){
            
            }
        }
        return (average /= strokes.size());
    }
    
    private static double calculateFeature(Stroke s, int feature){
        switch(feature) {
            case TIME_STROKE:
                return Features.timeStroke(s);
                
            case AVG_POINT_TIME:
                return Features.avgPointTime(s);
                
            case EUCLIDEAN_LENGTH:
                return Features.euclideanLength(s);
                
            case STROKE_LENGTH:
                return Features.strokeLength(s);
                
            case MANHATTAN_DISTANCE:
                return Features.manhattanDistance(s);
                
            case EUCLIDEAN_SPEED:
                return Features.euclideanSpeed(s);
                
            case TOTAL_SPEED:
                return Features.totalSpeed(s);
                
            case MANHATTAN_SPEED:
                return Features.manhattanSpeed(s);
                
            case ENDPOINT_CURVATURE:
                return Features.endpointCurvature(s);
                
            case TOTAL_CURVATURE:
                return Features.totalCurvature(s);
                
            case ABSOLUTE_CURVATURE:
                return Features.absoluteCurvature(s);
                
            case CURVATURE_CHANGES:
                return (double) Features.curvatureChanges(s).size();
                
            case STROKE_JERKINESS:
                return Features.strokeJerkiness(s);
                
            case START_TO_END_PRESSURE_DIFFERENCE:
                return Features.startToEndPressureDifference(s);
                
            case MIDDLE_TO_ENDS_PRESSURE_DIFFERENCE:
                return Features.middleToEndsPressureDifference(s);
                
            case AVERAGE_PRESSURE:
                return Features.averagePressure(s);
                
            case PRESSURE_DIFF:
                return Features.pressureDiff(s);
                
            case ABS_PRESSURE_DIFF:
                return Features.absPressureDiff(s);
                
            case PRESSURE_TIME:
                return Features.pressureTime(s);
                
            case WEIGHT:
                return Features.weight(s);
                
            case FIRST_EIGHTH_VERSUS_LAST_THIRD_TIME:
                return Features.firstEighthVersusLastThirdTime(s);
                
            case AVERAGE_TILT_X:
                return Features.averageTiltX(s);
                
            case AVERAGE_TILT_Y:
                return Features.averageTiltY(s);
                
            case SIZE_BOUNDING_BOX:
                return Features.sizeBoundingBox(s);
                
            case ANGLE_BOUNDING_BOX:
                return Features.angleBoundingBox(s);
                
            case AVERAGE_TILT:
                return Features.averageTilt(s);
                
            case TOP_SPEED:
                return Features.topSpeed(s);
                
            case SLOWEST_SPEED:
                return Features.slowestSpeed(s);
                
            case BEGINNING_ANGLE:
                return Features.beginningAngle(s);     
                
            case ASPECT_RATIO:
                return Features.aspectRatio(s); 
                
            case ASPECT_RATIO_LOG:
                return Features.aspectRatioLog(s);  
                
            case ENDPOINT_ANGLE:
                return Features.endpointAngle(s);  
                
            case STROKE_SHARPNESS:
                return Features.strokeSharpness(s);
                
            case LOG_AREA:
                return Features.logArea(s);
                
            case TOTAL_TILT:
                return Features.totalTilt(s);
                
            case NUM_INTERSECTIONS:
                return Features.numIntersections(s);
                
            case LONGEST_STRAIGHT:
                return Features.longestStraight(s);
                
            case CENTROID:
                return 0; // no actual average for this...
                
            case CENTER_DISTANCE:
                return Features.centerDistance(s);
            
            case SECOND_QUARTER_VERSUS_LAST_QUARTER_PRESSURE:
                return Features.secondQuarterVersusLastQuarterPressure(s);
                
            default:
                return 0.0;
        }
    }
    
}
